<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>

        /* 
            封装  继承  多态  
            继承:
                两个类(构造函数)之间的关系
            目的:
                公共内容提取出来 减少重复的代码 
                猫 狗 猴子 猪 马 鸡  都有 姓名 年龄 吃的方法
                每个都写的话  重复6遍 
                // 如果提取出来 给到 动物  只需要写一次 然后让
                //  猫 狗 猴子 猪 马 鸡 继承于动物 

                // 猫的实例(对象)使用了动物的属性和方法  
                // 猫是子类 
                // 动物是父类  

            // es5 
            //  1.原型链继承 
            //  子类的原型指向父类的实例 
            //  子类的prototype = new 父类();
            //  子类就继承了父类的属性和方法 
            //  缺点: 继承下来的不在自己身上 而是在原型上 

            //  2.借用构造函数继承 
            //  把父类(构造函数)当成普通函数调用 使用call改变父类(构造函数)的this指向
            //  子类(...args){
                    父类.call(this,...args)
                }
            //  优点: 属性继承到了自己身上 
            //  缺点: 不能继承方法
            
            // 3.组合继承 
            //  组合继承 = 原型链 + 借用构造函数继承(借用继承和call继承)
            //  子类(...args){
                    父类.call(this,...args)
                }
            //  子类.prototype = new 父类() 
            //  属性在自己身上 而且页继承了方法 
            // 缺点: 原型上多了一套属性   

            // 4. 拷贝继承 
            //  in  hasOwnProperty
            //  利用for in 循环遍历父类的实例 得到 键 和值 
            //  把得到的内容 添加到子类的原型上
            
            // 5.寄生继承  
            // Object.create(原型对象)

            var person = {
                name:'张三',
                age:18
            }

            var child = Object.create(person)
            // 返回一个新对象  新对象的原型就是 person 
            // 所以 child 就继承了 person的属性  

            function Person(name){
                this.name  = name;
            }

            Person.prototype.sayHello = function(){
                console.log('Hello'+this.name);
            }

            function Child(age,...args){
                Person.call(this,...args);
                this.age = age;
            }
            Child.prototype = Object.create(Person.prototype);
            // Child.prototype.constructor = Child
            Child.prototype.sayGood =  function(){
                console.log('今年'+this.age+'岁');
            }

            // es6 
            // class 子类 extends 父类{
                子类的constructor(值,...args){
                    super(...args)
                    this.属性 = 值 
                }

                方法(){

                }
            }
        
        
            // 冒充继承  
            //  浅拷贝 + 寄生继承  

            // 赋值  
            // var arr1 = [1,2,3,[4,5]];
            // var arr2 = arr1


            // 浅拷贝  
            // var arr1 = [1,2,3,[4,5]];
            // var arr2 = Object.assign([],arr1)

            // 深拷贝
            // 借用 JSON.parse(JSON.stringify()); 
        */
    </script>
</body>
</html>